/* Copyright 2007 Gearbox Software - http://www.gearboxsoft.com
 
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at
 
     http:www.apache.org/licenses/LICENSE-2.0
 
 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.*/
namespace GearBlog.Web.Utils
{
	using System;
	using System.Web.Security;
	using Castle.MonoRail.Framework;
	using GearBlog.Web.Models;

	/// <summary>
    /// Summary description for SecurityUtil
    /// </summary>
    public static class SecurityUtil
    {
    	private static AuthenticationAgentBase _authenticationAgent;

        public class Fields
        {
            public const string CurrentUser = "CurrentUser";
            //public const string CurrentUserProfile = "CurrentUserProfile";
            //public const string CurrentUserLocale = "CurrentUserLocale";

        }
		static SecurityUtil()
		{
			_authenticationAgent = new FormsAuthenticationAgent();
		}
		public static void SetAuthenticationAgent(AuthenticationAgentBase authenticationAgent)
		{
			_authenticationAgent = authenticationAgent;
		}
		public static void SetAuthenticationAgent(Type authenticationAgentType)
		{
			_authenticationAgent = (AuthenticationAgentBase) Activator.CreateInstance(authenticationAgentType);
		}
		
        public static User GetCurrentUser(IRailsEngineContext context)
        {
        	string token = context.Request.ReadCookie(FormsAuthentication.FormsCookieName);
			if (string.IsNullOrEmpty(token))
				return null;
			else
			{
				FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(token);
				return User.Find(int.Parse(ticket.Name));
			}
        }

        public static bool Authenticate(Controller controller, string userName, string password, bool isPersistent,
            string returnUrl)
        {
			
            //TODO: Implement rememberCredentials using Cookie
            User user = User.FindByUserName(userName);
            
            bool isAuthenticated;
            if (user != null)
                isAuthenticated = user.IsPasswordCorrect(password) & user.IsEnabled;
            else
                isAuthenticated = false;
            if (isAuthenticated)
            {
            	WriteAuthToken(controller.Context, user, isPersistent);
                if (!string.IsNullOrEmpty(returnUrl)) controller.Redirect(returnUrl);
            }

            return isAuthenticated;
        }
		private static void WriteAuthToken(IRailsEngineContext context, User user, bool isPersistent)
		{
			FormsAuthenticationTicket ticket=new FormsAuthenticationTicket(2, user.Id.ToString(), DateTime.Now, DateTime.Now.AddDays(30),isPersistent,string.Empty);
			string token = FormsAuthentication.Encrypt(ticket);
			if (isPersistent)
				context.Response.CreateCookie(FormsAuthentication.FormsCookieName, token, DateTime.Now.AddDays(30));
			else 
				context.Response.CreateCookie(FormsAuthentication.FormsCookieName, token);
		}
		private static void RemoveAuthToken(IRailsEngineContext context)
		{
			context.Response.CreateCookie(FormsAuthentication.FormsCookieName, string.Empty);
			context.Response.RemoveCookie(FormsAuthentication.FormsCookieName);
		}
        
        public static bool Logout(IRailsEngineContext context)
        {
            User user = GetCurrentUser(context);
            if (user != null)
            {
                RemoveAuthToken(context);
                return true;
            }
            else
                return false;

        }

    	public static bool AttemptLogin(Controller controller, string returnUrl)
    	{
			return _authenticationAgent.AttemptLogin(controller,returnUrl);
			
    	}


    	public static void ShowAccessDenied(Controller controller)
    	{
			_authenticationAgent.ShowAccessDenied(controller);
    	}
    }
}